package cn.sciento.transfer.infra.datasource.ddl;

import cn.sciento.core.exception.CommonException;import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.util.Assert;

public class MySqlTableScriptBuilder extends BaseTableScriptBuilder {
  public static final String CREATE_TABLE = "createTable";
  
  public static final String split = ",";
  
  public String getCreateTableScript(Connection connection, String tableName) throws SQLException {
    String sql = String.format("SHOW CREATE TABLE  %s", new Object[] { tableName });
    List<Map<String, Object>> mapList = doQuery(connection, sql, Boolean.valueOf(true));
    Assert.isTrue(CollectionUtils.isNotEmpty(mapList), "error.data_not_exists");
    return (String)((Map)mapList.get(0)).get("createTable");
  }
  
  public List<String> getTablePrimaryKey(Connection connection, String schemaName, String tableName) throws SQLException {
    String sql = String.format("SELECT%n\ttc.table_schema,%n\ttc.table_name,%n\ttc.constraint_type,%n\ttc.constraint_name,%n\tGROUP_CONCAT(kcu.COLUMN_NAME) as index_column_names%nFROM%n\tinformation_schema.table_constraints tc%n\tJOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu on kcu.constraint_name = tc.constraint_name and kcu.table_schema = tc.table_schema and kcu.table_name = tc.table_name%nWHERE%n\ttc.table_name = '%s'  -- 表名#1%n\tAND tc.TABLE_SCHEMA = '%s' -- 数据库名#2%n\tAND tc.constraint_type IN ('PRIMARY KEY', 'UNIQUE')%n\tGROUP BY %n\ttc.table_schema,%n\ttc.table_name,%n\ttc.constraint_type,%n\ttc.constraint_name%n\tORDER BY tc.CONSTRAINT_TYPE;", new Object[] { tableName, schemaName });
    List<Map<String, Object>> mapList = doQuery(connection, sql, Boolean.valueOf(true));
    if (CollectionUtils.isEmpty(mapList))
      throw new CommonException("can not find either of primaryKey and uniqueKey from table:" + tableName);
    List<String> primaryKey = findPrimaryKey(mapList);
    if (CollectionUtils.isEmpty(primaryKey))
      throw new CommonException("can not find either of primaryKey and uniqueKey from table:" + tableName);
    return primaryKey;
  }
  
  private List<String> findPrimaryKey(List<Map<String, Object>> mapList) {
    List<String> primaryKeys = new ArrayList<>(1);
    List<String> uniqueKeys = new ArrayList<>(1);
    for (Map<String, Object> data : mapList) {
      if ("PRIMARY KEY".equals(data.get("constraintType"))) {
        String indexColumnNames = (String)data.get("indexColumnNames");
        primaryKeys = parsePrimaryKey(indexColumnNames);
        continue;
      } 
      if ("UNIQUE".equals(data.get("constraintType"))) {
        String indexColumnNames = (String)data.get("indexColumnNames");
        uniqueKeys = parsePrimaryKey(indexColumnNames);
      } 
    } 
    if (CollectionUtils.isNotEmpty(primaryKeys))
      return primaryKeys; 
    if (CollectionUtils.isNotEmpty(uniqueKeys))
      return uniqueKeys; 
    return null;
  }
  
  public static interface constraintType {
    public static final String primaryKey = "PRIMARY KEY";
    
    public static final String unique = "UNIQUE";
  }
}
